package com.kye.express.business.order_detail;

import android.content.Context;

import com.baidu.mapapi.model.LatLng;
import com.baidu.trace.LBSTraceClient;
import com.baidu.trace.api.track.HistoryTrackRequest;
import com.baidu.trace.api.track.HistoryTrackResponse;
import com.baidu.trace.api.track.OnTrackListener;
import com.baidu.trace.api.track.TrackPoint;
import com.kye.base.Logger;
import com.kye.express.App;
import com.kye.express.business.map.MapUtils;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.express.view.ToastManager;
import com.kye.model.AppDatabase;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.UserSession;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.dstance.DstanceBean;
import com.kye.model.bean.logistics.LogisticsDriverInfoBean;
import com.kye.model.bean.logistics.LogisticsUrgeResultBean;
import com.kye.model.bean.logistics.RequestLogisticsDriverInfo;
import com.kye.model.bean.logistics.request.RequestLogisticsUrge;
import com.kye.model.bean.logistics.request.RequestPostLogisticsUrgeMessage;
import com.kye.model.bean.order.OrderDetailResultBean;
import com.kye.model.bean.order.OrderStatusBean;
import com.kye.model.bean.order.UrgeRecordBean;
import com.kye.model.bean.order.request.RequestDeleteOrder;
import com.kye.model.bean.order.request.RequestOrderDeliveryDstance;
import com.kye.model.bean.order.request.RequestOrderDetail;
import com.kye.model.bean.order.request.RequestOrderStatusProgress;
import com.kye.model.bean.user.User;
import com.kye.model.datasource.LogisticsDataSource;
import com.kye.model.datasource.OrderDataSource;

import org.reactivestreams.Publisher;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.processors.FlowableProcessor;
import io.reactivex.processors.PublishProcessor;
import io.reactivex.schedulers.Schedulers;

public interface OrderDetailContract {

    interface OrderDetailView extends IView, LoadingView, ErrorView {

        void onUser(User user);

        void getOrderDetailSuccess(OrderDetailResultBean orderDetailResultBean);

        void getOrderDetailFailed(String msg);

        void getOrderDetailFailed(Throwable e);

        void getOrderStatusProgressSuccess(List<OrderStatusBean> orderStatusBeans);

        void getOrderStatusProgressFailed(String msg);

        void postOrderUrgeSuccess(LogisticsUrgeResultBean logisticsUrgeResultBean);

        void postOrderUrgeMessageSuccess();

        void getOrderDeliveryDstance(DstanceBean dstanceBean);

        void onMoveCar(LatLng latLng);

        void deleteOrderSuccess(String s);

        void deleteOrderServerFailed(String msg);

        void deleteOrderNetFailed(String message);

        void updateOrderDeliveryDstance(DstanceBean dstanceBean);

        void getDriverInfoSuccess(LogisticsDriverInfoBean logisticsDriverInfoBean);

    }

    class OrderDetailPresenter extends BasePresenter<OrderDetailView> {

        private static final long TIME_LONG = 300;

        private FlowableProcessor<List<LatLng>> mTrackPointListResult = PublishProcessor.<List<LatLng>>create().toSerialized();


        OnTrackListener mOnTrackListener = new OnTrackListener() {

            @Override
            public void onHistoryTrackCallback(HistoryTrackResponse historyTrackResponse) {
                super.onHistoryTrackCallback(historyTrackResponse);
                List<TrackPoint> trackPoints = historyTrackResponse.getTrackPoints();
                Logger.d(historyTrackResponse);
                List<LatLng> latLngs = new ArrayList<>();
                if (trackPoints != null && trackPoints.size() > 1) {
                    for (int i = 0; i < trackPoints.size(); i++) {
                        latLngs.add(MapUtils.convertTrace2Map(trackPoints.get(i).getLocation()));
                    }
                    mTrackPointListResult.onNext(latLngs);
                }
            }
        };
        private OrderDataSource orderDataSource;
        private LogisticsDataSource logisticsDataSource;
        private LBSTraceClient mLBSTraceClient;

        public OrderDetailPresenter() {
            orderDataSource = new OrderDataSource();
            logisticsDataSource = new LogisticsDataSource();
        }

        @Override
        public void bind(OrderDetailView view) {
            super.bind(view);
            UserSession.getInstance().getUserForRx()
                    .compose(view.<User>bindToLifecycleDestroy())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<User>() {
                        @Override
                        public void accept(User user) throws Exception {
                            getView().onUser(user);
                        }
                    });

            mTrackPointListResult.flatMap(new Function<List<LatLng>, Publisher<LatLng>>() {

                @Override
                public Publisher<LatLng> apply(List<LatLng> latLngs) throws Exception {
                    return Flowable.create(new FlowableOnSubscribe<LatLng>() {
                        @Override
                        public void subscribe(FlowableEmitter<LatLng> e) throws Exception {
                            double jianju = TIME_LONG * 1000 / (latLngs.size() - 1);
                            for (int i = 0; i < latLngs.size() - 1; i++) {
                                LatLng startPoint = latLngs.get(i);
                                LatLng endPoint = latLngs.get(i + 1);

                                double slope = MapUtils.getSlope(startPoint, endPoint);
                                //是不是正向的标示（向上设为正向）
                                boolean isReverse = (startPoint.latitude > endPoint.latitude);

                                double intercept = MapUtils.getInterception(slope, startPoint);

                                int v = (int) jianju / 100;
//                                double xMoveDistance = isReverse ? MapUtils.getXMoveDistance(slope)
//                                        : -1 * MapUtils.getXMoveDistance(slope);

                                double xMoveDistance = isReverse ? MapUtils.getXMoveDistance(slope, startPoint, endPoint, v) : -1 * MapUtils.getXMoveDistance(slope, startPoint, endPoint, v);

                                int x = 0;
                                for (double j = startPoint.latitude; x < v; j = j - xMoveDistance, x++) {
//                                for (double j = startPoint.latitude;
//                                     !((j > endPoint.latitude) ^ isReverse);
//                                     j = j - xMoveDistance) {
                                    LatLng latLng;
                                    if (slope != Double.MAX_VALUE) {
                                        latLng = new LatLng(j, (j - intercept) / slope);
                                    } else {
                                        latLng = new LatLng(j, startPoint.longitude);
                                    }

                                    e.onNext(latLng);

                                    try {
                                        Thread.sleep(100);
                                    } catch (Throwable ignored) {}
                                }
                            }
                        }
                    }, BackpressureStrategy.DROP)
                            .subscribeOn(Schedulers.io());
                }
            })
                    .subscribeOn(Schedulers.io())
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<LatLng>() {
                        @Override
                        public void accept(LatLng latLng) throws Exception {
                            Logger.d(latLng);
                            getView().onMoveCar(latLng);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });
        }

        public Single<OpenApiResult<OrderDetailResultBean>> getOrderDetailSingle(String phone, String orderCode, String scoreCode, User user) {
            return
                    Single.just(new RequestOrderDetail(user.getPhone(), orderCode, scoreCode))
                            .subscribeOn(Schedulers.io())
                            .observeOn(Schedulers.io())
                            .flatMap(new Function<RequestOrderDetail, SingleSource<OpenApiResult<OrderDetailResultBean>>>() {
                                @Override
                                public SingleSource<OpenApiResult<OrderDetailResultBean>> apply(RequestOrderDetail requestOrderDetail) throws Exception {
                                    return orderDataSource.getOrderDetail(requestOrderDetail)
                                            .compose(getView().<OpenApiResult<OrderDetailResultBean>>bindToLifecycleDestroy());
                                }
                            })
                            .doOnSuccess(new Consumer<OpenApiResult<OrderDetailResultBean>>() {
                                @Override
                                public void accept(OpenApiResult<OrderDetailResultBean> orderDetailResultBeanOpenApiResult) throws Exception {
                                    if (!("1".equals(orderDetailResultBeanOpenApiResult.getData().getOrderMain().getGoodsState())))
                                        return;
                                    getOrderDeliveryDistanceInfo(user, orderCode);
                                }
                            })
                            // 获取司机信息
                            .doOnSuccess(new Consumer<OpenApiResult<OrderDetailResultBean>>() {
                                @Override
                                public void accept(OpenApiResult<OrderDetailResultBean> orderDetailResultBeanOpenApiResult) throws Exception {
                                    if (orderDetailResultBeanOpenApiResult.isSuccess()) {
//                                        0:处理中 1:已调度(根据地址，10km以内显示地图) 2:已到达 3:已取货
                                        String goodsState = orderDetailResultBeanOpenApiResult.getData().getOrderMain().getGoodsState();
                                        switch (goodsState) {
                                            case "1":
                                            case "2":
                                            case "3":
                                                getDriverInfo(user.getPhone(), orderCode);
                                                break;
                                            default:
                                                break;
                                        }
                                    }
                                }
                            })
                            .observeOn(AndroidSchedulers.mainThread());
        }

        private void getOrderDeliveryDistanceInfo(User user, String orderCode) {
            orderDataSource.getOrderDeliveryDstance(new RequestOrderDeliveryDstance(user.getPhone(), orderCode))
                    .filter(new Predicate<OpenApiResult<DstanceBean>>() {
                        @Override
                        public boolean test(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData().getDistance() <= 10F;
                        }
                    })
                    .map(new Function<OpenApiResult<DstanceBean>, DstanceBean>() {
                        @Override
                        public DstanceBean apply(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData();
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DstanceBean>() {
                        @Override
                        public void accept(DstanceBean dstanceBean) throws Exception {
                            getView().getOrderDeliveryDstance(dstanceBean);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });
        }

        private void updateOrderDeliveryDistanceInfo(User user, String orderCode) {
            orderDataSource.getOrderDeliveryDstance(new RequestOrderDeliveryDstance(user.getPhone(), orderCode))
                    .filter(new Predicate<OpenApiResult<DstanceBean>>() {
                        @Override
                        public boolean test(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData().getDistance() <= 10F;
                        }
                    })
                    .map(new Function<OpenApiResult<DstanceBean>, DstanceBean>() {
                        @Override
                        public DstanceBean apply(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData();
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DstanceBean>() {
                        @Override
                        public void accept(DstanceBean dstanceBean) throws Exception {
                            getView().updateOrderDeliveryDstance(dstanceBean);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });
        }

        private void getDriverInfo(String phone, String orderCode) {
            Single.just(new RequestLogisticsDriverInfo())
                    .doOnSuccess(new Consumer<RequestLogisticsDriverInfo>() {
                        @Override
                        public void accept(RequestLogisticsDriverInfo requestLogisticsDriverInfo) throws Exception {
                            requestLogisticsDriverInfo.setPhone(phone);
                            requestLogisticsDriverInfo.setWaybill(orderCode);
                            requestLogisticsDriverInfo.setType("0");
                        }
                    })
                    .flatMap(new Function<RequestLogisticsDriverInfo, SingleSource<OpenApiResult<LogisticsDriverInfoBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<LogisticsDriverInfoBean>> apply(RequestLogisticsDriverInfo requestLogisticsDriverInfo) throws Exception {
                            return logisticsDataSource.getLogisticsDriverInfo(requestLogisticsDriverInfo)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<LogisticsDriverInfoBean>() {
                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<LogisticsDriverInfoBean> result, LogisticsDriverInfoBean logisticsDriverInfoBean) {
                            getView().getDriverInfoSuccess(logisticsDriverInfoBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<LogisticsDriverInfoBean> result, int code, String msg) {

                        }

                        @Override
                        public void onOtherError(Throwable e) {

                        }

                        @Override
                        public void onLoaded() {

                        }
                    });
        }

        /**
         * 订单详情
         * @param phone
         * @param orderCode
         * @param scoreCode
         * @param user
         */
        public void getOrderDetail(String phone, String orderCode, String scoreCode, User user) {
            getOrderDetailSingle(phone, orderCode, scoreCode, user)
                    .subscribe(new OpenApiResultObserver<OrderDetailResultBean>() {
                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<OrderDetailResultBean> result, OrderDetailResultBean orderDetailResultBean) {
                            getView().getOrderDetailSuccess(orderDetailResultBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<OrderDetailResultBean> result, int code, String msg) {
                            getView().getOrderDetailFailed(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().getOrderDetailFailed(e);
                        }

                        @Override
                        public void onLoaded() {

                        }
                    });
        }

        public void refreshOrderDetail(String phone, String orderCode, String scoreCode, User user) {
            getOrderDetailSingle(phone, orderCode, scoreCode, user)
                    .subscribe(new OpenApiResultObserver<OrderDetailResultBean>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<OrderDetailResultBean> result, OrderDetailResultBean orderDetailResultBean) {
                            getView().getOrderDetailSuccess(orderDetailResultBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<OrderDetailResultBean> result, int code, String msg) {
                            ToastManager.showCenterForShort(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            ToastManager.showCenterForShort(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        /**
         * 订单状态路由
         *
         * @param orderDetailResultBean
         * @param userInfo
         */
        public void getOrderStatusProgress(final OrderDetailResultBean orderDetailResultBean, final User userInfo) {
            Single.just(new RequestOrderStatusProgress())
                    .subscribeOn(Schedulers.io())
                    .doOnSuccess(new Consumer<RequestOrderStatusProgress>() {
                        @Override
                        public void accept(RequestOrderStatusProgress requestOrderStatusProgress) throws Exception {
                            requestOrderStatusProgress.setPhone(userInfo.getPhone());
                            requestOrderStatusProgress.setOrderCode(orderDetailResultBean.getOrderMain().getOrderCode());
                        }
                    })
                    .flatMap(new Function<RequestOrderStatusProgress, SingleSource<OpenApiResult<List<OrderStatusBean>>>>() {
                        @Override
                        public SingleSource<OpenApiResult<List<OrderStatusBean>>> apply(RequestOrderStatusProgress requestOrderStatusProgress) throws Exception {
                            return orderDataSource
                                    .getOrderStatusProgress(requestOrderStatusProgress)
                                    .compose(getView().<OpenApiResult<List<OrderStatusBean>>>bindToLifecycleDestroy());
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<List<OrderStatusBean>>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<List<OrderStatusBean>> result, List<OrderStatusBean> orderStatusBeans) {
                            getView().getOrderStatusProgressSuccess(orderStatusBeans);
                        }

                        @Override
                        public void onApiError(OpenApiResult<List<OrderStatusBean>> result, int code, String msg) {
                            getView().getOrderStatusProgressFailed(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().getOrderStatusProgressFailed(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        public Observable<List<OrderStatusBean>> handleOrderStatusProgressDataObservable(List<OrderStatusBean> orderStatusBeans) {
            return
                    Observable.just(orderStatusBeans)
                            .doOnNext(new Consumer<List<OrderStatusBean>>() {
                                @Override
                                public void accept(List<OrderStatusBean> orderStatusBeans) throws Exception {
                                    orderStatusBeans.get(orderStatusBeans.size() - 1).setCurrentState(true);
                                }
                            })
//                            .doOnNext(new Consumer<List<OrderStatusBean>>() {
//                                @Override
//                                public void accept(List<OrderStatusBean> orderStatusBeans) throws Exception {
//                                    if (orderStatusBeans.size() < 4) {
//                                        int start = orderStatusBeans.size();
//                                        List<OrderStatusBean> defaultList = OrderStatusBean.getDefaultList();
//                                        orderStatusBeans.addAll(defaultList.subList(start, defaultList.size()));
//                                    }
//                                }
//                            })
                            .doOnNext(new Consumer<List<OrderStatusBean>>() {
                                @Override
                                public void accept(List<OrderStatusBean> lists) throws Exception {
                                    Collections.sort(lists, new Comparator<OrderStatusBean>() {
                                        @Override
                                        public int compare(OrderStatusBean o1, OrderStatusBean o2) {
                                            return Integer.parseInt(o2.getState()) - Integer.parseInt(o1.getState());
                                        }
                                    });
                                }
                            });
        }

        /**
         * 崔健
         *
         * @param orderCode
         * @param userInfo
         */
        public void postOrderUrge(String orderCode, User userInfo) {
            Single.just(new RequestLogisticsUrge())
                    .doOnSuccess(new Consumer<RequestLogisticsUrge>() {
                        @Override
                        public void accept(RequestLogisticsUrge requestLogisticsUrge) throws Exception {
                            requestLogisticsUrge.setPhone(userInfo.getPhone());
                            requestLogisticsUrge.setSource("APP");
                            requestLogisticsUrge.setType("0"); // 类型（0 取 1派）
                            requestLogisticsUrge.setWaybill(orderCode);
                        }
                    })
                    .flatMap(new Function<RequestLogisticsUrge, SingleSource<OpenApiResult<LogisticsUrgeResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<LogisticsUrgeResultBean>> apply(RequestLogisticsUrge requestLogisticsUrge) throws Exception {
                            return logisticsDataSource
                                    .postLogisticsUrge(requestLogisticsUrge)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<LogisticsUrgeResultBean>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<LogisticsUrgeResultBean> result, LogisticsUrgeResultBean logisticsUrgeResultBean) {
                            // save urge post time
                            getView().postOrderUrgeSuccess(logisticsUrgeResultBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<LogisticsUrgeResultBean> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        /**
         * 发送留言
         *
         * @param urgeMessage
         */
        public void postOrderUrgeMessage(String urgeMessage, User userInfo, OrderDetailResultBean orderDetailResultBean) {
            Single.just(new RequestPostLogisticsUrgeMessage())
                    .doOnSuccess(new Consumer<RequestPostLogisticsUrgeMessage>() {
                        @Override
                        public void accept(RequestPostLogisticsUrgeMessage requestPostLogisticsUrgeMessage) throws Exception {
                            requestPostLogisticsUrgeMessage.setPhone(userInfo.getPhone());
                            requestPostLogisticsUrgeMessage.setRemark(urgeMessage);
                            requestPostLogisticsUrgeMessage.setWaybill(orderDetailResultBean.getOrderMain().getOrderCode());
                        }
                    })
                    .flatMap(new Function<RequestPostLogisticsUrgeMessage, SingleSource<OpenApiResult<Object>>>() {
                        @Override
                        public SingleSource<OpenApiResult<Object>> apply(RequestPostLogisticsUrgeMessage requestPostLogisticsUrgeMessage) throws Exception {
                            return logisticsDataSource
                                    .postLogisticsUrgeMessage(requestPostLogisticsUrgeMessage)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object o) {
                            getView().postOrderUrgeMessageSuccess();
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        public void getHistoryTrack(String terminalID, User user, String orderCode) {
            Observable.interval(0, TIME_LONG, TimeUnit.SECONDS)
                    .compose(getView().bindToLifecycleDestroy())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            Logger.d("开始请求鹰眼");

                            int tag = 1;
                            long serviceId = 126686;
                            String entityName = terminalID;
                            HistoryTrackRequest historyTrackRequest = new HistoryTrackRequest(tag, serviceId, entityName);
                            long startTime = (System.currentTimeMillis() / 1000) - TIME_LONG;
                            long endTime = System.currentTimeMillis() / 1000;
                            historyTrackRequest.setStartTime(startTime);
                            historyTrackRequest.setEndTime(endTime);
                            
                            mLBSTraceClient.queryHistoryTrack(historyTrackRequest, mOnTrackListener);

                            updateOrderDeliveryDistanceInfo(user, orderCode);
                        }
                    });
        }

        public void saveUrgePostTime(String orderCode) {
            Single.just(orderCode)
                    .map(new Function<String, UrgeRecordBean>() {
                        @Override
                        public UrgeRecordBean apply(String orderCode) throws Exception {
                            UrgeRecordBean urgeRecordBean = new UrgeRecordBean();
                            urgeRecordBean.setCode(orderCode);
                            Date date = new Date();
                            urgeRecordBean.setTime(date.getTime());
                            return urgeRecordBean;
                        }
                    })
                    .doOnSuccess(new Consumer<UrgeRecordBean>() {
                        @Override
                        public void accept(UrgeRecordBean urgeRecordBean) throws Exception {
                            AppDatabase.getInstance(App.getContext()).urgeRecordDao()
                                    .insert(urgeRecordBean);
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<UrgeRecordBean>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(UrgeRecordBean urgeRecordBean) {
                            Logger.d("saveUrgePostTime success");
                        }

                        @Override
                        public void onError(Throwable e) {
                            Logger.d("saveUrgePostTime failed");
                        }
                    });

        }

        public void initLBSTraceClient(Context context) {
            if (mLBSTraceClient == null) mLBSTraceClient = new LBSTraceClient(context);
        }

        public void deleteOrder(String phone, String orderCode) {
            Single.just(new RequestDeleteOrder())
                    .doOnSuccess(new Consumer<RequestDeleteOrder>() {
                        @Override
                        public void accept(RequestDeleteOrder requestDeleteOrder) throws Exception {
                            requestDeleteOrder.setOrderCode(orderCode);
                            requestDeleteOrder.setPhone(phone);
                        }
                    })
                    .flatMap(new Function<RequestDeleteOrder, SingleSource<OpenApiResult<Object>>>() {
                        @Override
                        public SingleSource<OpenApiResult<Object>> apply(RequestDeleteOrder requestDeleteOrder) throws Exception {
                            return orderDataSource.deleteOrder(requestDeleteOrder)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object s) {
                            getView().deleteOrderSuccess(s.toString());
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                            getView().deleteOrderServerFailed(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().deleteOrderNetFailed(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }
    }
}
